import os
import sys
import argparse
import time
import subprocess
import json
import shutil
import zipfile
import tempfile

def download_extensions_from_cloud(username, target_dir):
    """
    从云端下载扩展程序数据
    """
    try:
        import requests
        
        backup_filename = f"{username}_extensions_backup.zip"
        cloud_url = f"https://auth-share.oss-cn-shenzhen.aliyuncs.com/{backup_filename}"
        
        print(f"📥 正在从云端下载扩展数据...")
        response = requests.get(cloud_url)
        response.raise_for_status()
        
        # 保存压缩包
        with open(backup_filename, "wb") as f:
            f.write(response.content)
        
        # 解压到目标目录
        with zipfile.ZipFile(backup_filename, 'r') as zipf:
            zipf.extractall(target_dir)
        
        # 清理临时文件
        os.remove(backup_filename)
        
        print(f"✅ 扩展数据下载成功")
        return True
        
    except Exception as e:
        print(f"⚠️  从云端下载扩展数据失败: {e}")
        return False

def copy_extensions_data(source_profile_dir, target_profile_dir):
    """
    复制Chrome扩展程序数据到目标配置目录
    """
    try:
        extensions_dirs = [
            "Extensions",
            "Extension State", 
            "Extension Rules",
            "Local Extension Settings",
            "Sync Extension Settings"
        ]
        
        # 可能是文件而不是目录的项目
        extensions_files = [
            "Extension Cookies",
            "Extension Cookies-journal"
        ]
        
        copied_count = 0
        
        # 复制目录
        for ext_dir in extensions_dirs:
            source_path = os.path.join(source_profile_dir, ext_dir)
            target_path = os.path.join(target_profile_dir, ext_dir)
            
            if os.path.exists(source_path) and os.path.isdir(source_path):
                try:
                    if os.path.exists(target_path):
                        shutil.rmtree(target_path)
                    shutil.copytree(source_path, target_path)
                    copied_count += 1
                    print(f"📦 复制扩展目录: {ext_dir}")
                except Exception as e:
                    print(f"⚠️  复制目录 {ext_dir} 失败: {e}")
        
        # 复制文件
        for ext_file in extensions_files:
            source_path = os.path.join(source_profile_dir, ext_file)
            target_path = os.path.join(target_profile_dir, ext_file)
            
            if os.path.exists(source_path) and os.path.isfile(source_path):
                try:
                    # 确保目标目录存在
                    os.makedirs(os.path.dirname(target_path), exist_ok=True)
                    shutil.copy2(source_path, target_path)
                    copied_count += 1
                    print(f"📄 复制扩展文件: {ext_file}")
                except Exception as e:
                    print(f"⚠️  复制文件 {ext_file} 失败: {e}")
        
        if copied_count > 0:
            print(f"✅ 成功复制 {copied_count} 个扩展数据项")
            return True
        else:
            print(f"⚠️  没有找到任何可复制的扩展数据")
            return False
        
    except Exception as e:
        print(f"❌ 复制扩展数据失败: {e}")
        print(f"💡 提示: 请确保Chrome浏览器已关闭，然后重试")
        return False

def apply_auth_state_to_profile(auth_file_name, profile_dir, chrome_path):
    """
    将登录状态应用到运行中的Chrome实例
    """
    try:
        # 读取登录状态文件
        if not os.path.exists(auth_file_name):
            return False
            
        with open(auth_file_name, 'r', encoding='utf-8') as f:
            auth_state = json.load(f)
        
        cookies = auth_state.get('cookies', [])
        origins = auth_state.get('origins', [])
        
        if not cookies and not origins:
            print("⚠️  登录状态文件为空")
            return False
        
        print(f"📄 正在应用登录状态: {len(cookies)} 个cookies, {len(origins)} 个origins")
        
        # 等待Chrome完全启动
        time.sleep(2)
        
        # 使用Playwright连接到运行中的Chrome实例
        try:
            from playwright.sync_api import sync_playwright
            
            with sync_playwright() as p:
                # 连接到运行中的Chrome实例（使用相同的用户数据目录）
                try:
                    # 尝试连接到现有的Chrome实例
                    context = p.chromium.launch_persistent_context(
                        user_data_dir=profile_dir,
                        headless=True,  # 隐藏模式，只用于设置状态
                        channel="chrome" if "chrome.exe" in chrome_path.lower() else None,
                        args=[
                            '--disable-web-security',
                            '--no-first-run',
                            '--no-default-browser-check',
                            '--disable-extensions',  # 禁用扩展避免冲突
                        ]
                    )
                except Exception as e:
                    print(f"⚠️  无法连接到运行中的Chrome: {e}")
                    print("💡 将尝试手动复制登录数据到用户目录...")
                    
                    # 手动复制cookies数据到Chrome的数据库文件
                    import sqlite3
                    
                    cookies_db_path = os.path.join(profile_dir, "Default", "Cookies")
                    if os.path.exists(cookies_db_path):
                        # 备份原有cookies数据库
                        backup_path = cookies_db_path + ".backup"
                        try:
                            shutil.copy2(cookies_db_path, backup_path)
                            
                            # 连接到cookies数据库
                            conn = sqlite3.connect(cookies_db_path)
                            cursor = conn.cursor()
                            
                            # 清理旧的cookies数据
                            cursor.execute("DELETE FROM cookies")
                            
                            # 插入新的cookies
                            for cookie in cookies:
                                if 'name' in cookie and 'value' in cookie and 'domain' in cookie:
                                    # 插入cookie数据
                                    cursor.execute("""
                                        INSERT INTO cookies (creation_utc, host_key, name, value, path, expires_utc, is_secure, is_httponly, last_access_utc, has_expires, is_persistent, priority, encrypted_value, samesite, source_scheme)
                                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', 0, 1)
                                    """, (
                                        int(time.time() * 1000000),  # creation_utc
                                        cookie['domain'],
                                        cookie['name'],
                                        cookie['value'],
                                        cookie.get('path', '/'),
                                        int(cookie.get('expires', time.time() + 365*24*3600) * 1000000),  # expires_utc
                                        1 if cookie.get('secure', False) else 0,
                                        1 if cookie.get('httpOnly', False) else 0,
                                        int(time.time() * 1000000),  # last_access_utc
                                        1,  # has_expires
                                        1,  # is_persistent
                                        1   # priority
                                    ))
                            
                            conn.commit()
                            conn.close()
                            
                            print(f"✅ 直接将 {len(cookies)} 个cookies写入Chrome数据库")
                            return True
                            
                        except Exception as db_error:
                            print(f"⚠️  数据库操作失败: {db_error}")
                            # 恢复备份
                            if os.path.exists(backup_path):
                                shutil.copy2(backup_path, cookies_db_path)
                            return False
                    
                    return False
                
                # 创建页面
                page = context.new_page()
                
                # 应用cookies
                if cookies:
                    try:
                        valid_cookies = []
                        for cookie in cookies:
                            # 确保必要字段存在
                            if 'name' in cookie and 'value' in cookie and 'domain' in cookie:
                                valid_cookies.append(cookie)
                        
                        if valid_cookies:
                            context.add_cookies(valid_cookies)
                            print(f"🍪 应用了 {len(valid_cookies)} 个cookies")
                    except Exception as e:
                        print(f"⚠️  应用cookies失败: {e}")
                
                # 应用localStorage
                if origins:
                    try:
                        for origin_data in origins:
                            origin = origin_data.get('origin')
                            local_storage = origin_data.get('localStorage', [])
                            
                            if origin and local_storage:
                                # 访问相应的域名
                                try:
                                    page.goto(origin, wait_until='domcontentloaded', timeout=10000)
                                    
                                    # 设置localStorage
                                    for item in local_storage:
                                        if 'name' in item and 'value' in item:
                                            page.evaluate(f"localStorage.setItem('{item['name']}', '{item['value']}')")
                                            
                                    print(f"💾 在 {origin} 应用了 {len(local_storage)} 个localStorage项")
                                except Exception as origin_error:
                                    print(f"⚠️  访问 {origin} 失败: {origin_error}")
                    except Exception as e:
                        print(f"⚠️  应用localStorage失败: {e}")
                
                # 关闭临时浏览器
                context.close()
                return True
                
        except ImportError:
            print("⚠️  Playwright未安装，无法应用登录状态")
            return False
        except Exception as e:
            print(f"⚠️  应用登录状态时出错: {e}")
            return False
            
    except Exception as e:
        print(f"⚠️  读取登录状态文件失败: {e}")
        return False
    """
    将登录状态应用到Chrome用户配置目录
    """
    try:
        # 读取登录状态文件
        if not os.path.exists(auth_file_name):
            return False
            
        with open(auth_file_name, 'r', encoding='utf-8') as f:
            auth_state = json.load(f)
        
        cookies = auth_state.get('cookies', [])
        origins = auth_state.get('origins', [])
        
        if not cookies and not origins:
            print("⚠️  登录状态文件为空")
            return False
        
        # 启动临时Chrome实例来设置登录状态
        try:
            from playwright.sync_api import sync_playwright
            
            with sync_playwright() as p:
                # 使用相同的用户数据目录启动浏览器
                context = p.chromium.launch_persistent_context(
                    user_data_dir=profile_dir,
                    headless=True,  # 隐藏模式，只用于设置状态
                    channel="chrome" if "chrome.exe" in chrome_path.lower() else None,
                    args=[
                        '--disable-web-security',
                        '--no-first-run',
                        '--no-default-browser-check'
                    ]
                )
                
                # 创建页面
                page = context.new_page()
                
                # 应用cookies
                if cookies:
                    try:
                        await_cookies = []
                        for cookie in cookies:
                            # 确保必要字段存在
                            if 'name' in cookie and 'value' in cookie and 'domain' in cookie:
                                await_cookies.append(cookie)
                        
                        if await_cookies:
                            context.add_cookies(await_cookies)
                            print(f"🍪 应用了 {len(await_cookies)} 个cookies")
                    except Exception as e:
                        print(f"⚠️  应用cookies失败: {e}")
                
                # 应用localStorage
                if origins:
                    try:
                        for origin_data in origins:
                            origin = origin_data.get('origin')
                            local_storage = origin_data.get('localStorage', [])
                            
                            if origin and local_storage:
                                # 访问相应的域名
                                page.goto(origin, wait_until='domcontentloaded', timeout=10000)
                                
                                # 设置localStorage
                                for item in local_storage:
                                    if 'name' in item and 'value' in item:
                                        page.evaluate(f"localStorage.setItem('{item['name']}', '{item['value']}')")
                                        
                                print(f"💾 在 {origin} 应用了 {len(local_storage)} 个localStorage项")
                    except Exception as e:
                        print(f"⚠️  应用localStorage失败: {e}")
                
                # 关闭临时浏览器
                context.close()
                return True
                
        except ImportError:
            print("⚠️  Playwright未安装，无法应用登录状态")
            return False
        except Exception as e:
            print(f"⚠️  应用登录状态时出错: {e}")
            return False
            
    except Exception as e:
        print(f"⚠️  读取登录状态文件失败: {e}")
        return False

def find_chrome_executable():
    """查找系统中的Chrome可执行文件"""
    possible_paths = [
        r"C:\Program Files\Google\Chrome\Application\chrome.exe",
        r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
        os.path.expanduser(r"~\AppData\Local\Google\Chrome\Application\chrome.exe"),
    ]
    
    for path in possible_paths:
        if os.path.isfile(path):
            print(f"✅ 找到Chrome: {path}")
            return path
    
    # 如果都没找到，尝试命令行方式
    try:
        result = subprocess.run(["chrome", "--version"], 
                               capture_output=True, text=True, timeout=5)
        if result.returncode == 0:
            print(f"✅ 找到Chrome: chrome")
            return "chrome"
    except Exception:
        pass
        
    print("❌ 未找到Chrome浏览器")
    return None

def open_browser_independent(username=None, count=1, target_url=None):
    """
    启动独立的Chrome浏览器进程，脚本关闭后浏览器继续使用
    """
    try:
        # 获取用户名
        if username is None:
            try:
                from config import USERNAME
                username = USERNAME
            except ImportError:
                username = None
                
        # 获取目标网址
        if target_url is None:
            try:
                from config import TARGET_URL
                target_url = TARGET_URL
            except ImportError:
                target_url = "https://www.geekbi.com"  # 默认值
                
        if not username:
            print("❌ 错误：未指定用户名")
            return False
        
        # 查找Chrome可执行文件
        chrome_path = find_chrome_executable()
        if not chrome_path:
            print("❌ 错误：未找到Chrome浏览器")
            print("请安装Google Chrome浏览器")
            return False
            
        # 尝试下载或使用本地登录状态文件
        auth_file_name = f"{username}_auth_state.json"
        has_auth_state = False
      
        try:
            import requests
            cloud_url = f"https://auth-share.oss-cn-shenzhen.aliyuncs.com/{auth_file_name}"
            response = requests.get(cloud_url)
            response.raise_for_status()
            
            with open(auth_file_name, "wb") as f:
                f.write(response.content)
            print(f"✅ 下载登录状态成功")
            has_auth_state = True
        except Exception as e:
            print(f"⚠️  登录状态文件不存在或下载失败: {e}")
            print(f"💡 这是正常的，第一次使用时需要手动登录一次")
            has_auth_state = False
        
        # 尝试下载扩展程序数据
        extensions_file_name = f"{username}_extensions_backup.zip"
        has_extensions_data = False
        
        print(f"📥 尝试从云端下载扩展程序数据: {extensions_file_name}")
        try:
            import requests
            cloud_url = f"https://auth-share.oss-cn-shenzhen.aliyuncs.com/{extensions_file_name}"
            response = requests.get(cloud_url)
            response.raise_for_status()
            print(f"✅ 找到云端扩展数据")
            has_extensions_data = True
            # 暂时不下载，在需要时才下载
        except Exception as e:
            print(f"⚠️  扩展程序数据不存在或检查失败: {e}")
            print(f"💡 提示: 请先使用 login_enhanced.py 完成登录和扩展备份")
            has_extensions_data = False
        
        print(f"🚀 正在启动 {count} 个独立的Chrome浏览器...")
        
        browsers_started = []
        base_profile_dir = os.path.join(os.getcwd(), "browser_profiles", username)
        os.makedirs(base_profile_dir, exist_ok=True)
        
        # 使用共享的用户数据目录，所有浏览器实例共享相同配置
        shared_profile_dir = os.path.join(base_profile_dir, "shared_profile")
        init_marker_file = os.path.join(shared_profile_dir, ".initialized")
        need_init = not os.path.exists(init_marker_file)
        
        if need_init:
            print("🔄 首次使用，初始化共享用户配置...")
            os.makedirs(shared_profile_dir, exist_ok=True)
            
            # 应用登录状态
            if has_auth_state:
                print("🔄 正在应用登录状态...")
                try:
                    # 创建基本的Chrome配置结构
                    default_dir = os.path.join(shared_profile_dir, "Default")
                    os.makedirs(default_dir, exist_ok=True)
                    
                    # 使用Playwright初始化和应用登录状态
                    success = apply_auth_state_to_profile(auth_file_name, shared_profile_dir, chrome_path)
                    if success:
                        print("✅ 登录状态初始化成功")
                    else:
                        print("⚠️  登录状态初始化失败")
                except Exception as e:
                    print(f"⚠️  登录状态初始化出错: {e}")
            
            # 应用扩展程序数据
            if has_extensions_data:
                print("🔄 正在应用扩展程序数据...")
                try:
                    if download_extensions_from_cloud(username, shared_profile_dir):
                        print("✅ 扩展程序数据初始化成功")
                    else:
                        print("⚠️  扩展程序数据初始化失败")
                except Exception as e:
                    print(f"⚠️  扩展程序数据初始化出错: {e}")
            
            # 创建初始化标记文件
            try:
                with open(init_marker_file, 'w', encoding='utf-8') as f:
                    f.write(f"Initialized at {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                    f.write(f"Username: {username}\n")
                    f.write(f"Auth state: {'Yes' if has_auth_state else 'No'}\n")
                    f.write(f"Extensions: {'Yes' if has_extensions_data else 'No'}\n")
                print("✅ 共享配置初始化完成")
            except Exception as e:
                print(f"⚠️  创建初始化标记失败: {e}")
        else:
            print(f"💾 使用已有的共享用户配置: {os.path.relpath(shared_profile_dir, os.getcwd())}/")
        
        for i in range(count):
            browser_index = i + 1
            
            print(f"启动第 {browser_index} 个Chrome浏览器...")
            
            # 所有浏览器实例使用相同的共享配置目录
            profile_dir = shared_profile_dir
            
            # 构建Chrome启动参数
            chrome_args = [
                chrome_path,
                f"--user-data-dir={profile_dir}",
                "--start-maximized",
                target_url
            ]
            
            try:
                # 启动独立的Chrome进程
                process = subprocess.Popen(
                    chrome_args,
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                    stdin=subprocess.DEVNULL,
                    creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == 'win32' else 0
                )
                
                browsers_started.append({
                    "process": process,
                    "profile_dir": profile_dir,
                    "browser_index": browser_index
                })
                
                print(f"✅ [浏览器{browser_index}] Chrome进程启动成功 (PID: {process.pid})")
                time.sleep(2)  # 等待Chrome完全启动
                
            except Exception as e:
                print(f"❌ [浏览器{browser_index}] 启动失败: {e}")
                continue
        
        if browsers_started:
            print(f"\n✅ 成功启动 {len(browsers_started)} 个Chrome浏览器")
            print("🌐 您可以在每个Chrome中操作极鲸云平台")
            print(f"💾 共享用户数据目录: {os.path.relpath(shared_profile_dir, os.getcwd())}/")
            if has_auth_state or not need_init:
                print("🔑 网站登录状态已应用")
            if has_extensions_data or not need_init:
                print("🔌 扩展程序数据已应用")
            print("\n📋 操作说明:")
            print("- 这些Chrome浏览器现在独立运行")
            print("- 您可以安全地关闭此终端窗口")
            print("- 所有浏览器实例共享相同的用户数据")
            print("- 登录状态和插件设置在所有实例中同步")
            print("- 在任意一个实例中的操作都会自动保存")
            print("\n⚠️  重要提示:")
            if not has_auth_state and need_init:
                print("- 第一次使用时需要手动登录一次")
            if not has_extensions_data and need_init:
                print("- 如需扩展程序支持，请先使用 login.py")
            print("- 所有浏览器实例使用相同的共享数据目录")
            print("- 重复运行时会复用已有的配置和状态")
            print("- 登录状态和扩展数据在所有实例间共享")
            
            print("\n⏱️  5秒后自动退出脚本...")
            for i in range(5, 0, -1):
                print(f"   {i}...")
                time.sleep(1)
            
            print("\n🎉 脚本已完成！Chrome浏览器独立运行中")
            print("💡 提示: 您现在可以安全地关闭此终端窗口")
            return True
        else:
            print("\n❌ 没有成功启动任何浏览器")
            return False
        
    except Exception as e:
        print(f"❌ 启动浏览器失败: {e}")
        return False

def parse_arguments():
    parser = argparse.ArgumentParser(
        description='极鲸云多点登录工具 - 独立进程版',
        epilog='''使用示例:
  python open_independent.py -u 13800138000       # 指定用户名
  python open_independent.py -u 13800138000 -c 3  # 多个浏览器
  python open_independent.py --url https://example.com  # 指定目标网址
  python open_independent.py -u user -c 2 --url https://example.com  # 同时指定多个参数
        '''
    )
    parser.add_argument('-u', '--username', help='用户名（手机号或邮箱）')
    parser.add_argument('-c', '--count', type=int, default=1, help='浏览器数量（默认为1）')
    parser.add_argument('--url', '--target-url', dest='target_url',
                       help='目标网址（默认使用config.py中的TARGET_URL）')
    return parser.parse_args()

if __name__ == "__main__":
    try:
        args = parse_arguments()
        
        print("=" * 50)
        print("极鲸云多点登录工具 - 独立进程版")
        print("=" * 50)
        print("🎯 特性: 脚本关闭后浏览器继续使用")
        print("=" * 50)
        
        username = args.username
        count = args.count
        target_url = args.target_url
        
        if username:
            print(f"👤 用户名: {username}")
        print(f"🌐 浏览器数量: {count}")
        if target_url:
            print(f"🎯 目标网址: {target_url}")
        print()
        
        if count <= 0:
            print("❌ 错误：浏览器数量必须大于0")
            exit(1)
            
        success = open_browser_independent(username, count, target_url)
        
        if success:
            print("\n🎉 任务完成！")
        else:
            print("\n❌ 任务失败！")
            
    except KeyboardInterrupt:
        print("\n🚫 用户取消操作")
    except Exception as e:
        print(f"\n💥 程序遇到未知错误: {e}")